﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using SkiaSharp;

namespace Lazy.Captcha.Core
{
    public class DefaultFontFamilies
    {
        public static readonly DefaultFontFamilies Instance = new DefaultFontFamilies();
        private static readonly List<SKTypeface> _fontFamilies = [];

        private static Dictionary<string, string> FamilyNameMapper { get; set; } = new()
        {
            { "actionj", "Action Jackson" },
            { "epilog", "Epilog" },
            { "fresnel", "Fresnel" },
            { "headache", "Tom's Headache" },
            { "lexo", "Lexographer" },
            { "prefix", "Prefix" },
            { "progbot", "PROG.BOT" },
            { "ransom", "Ransom" },
            { "robot", "Robot Teacher" },
            { "scandal", "Potassium Scandal" },
            { "kaiti", "FZKai-Z03" }
        };

        static DefaultFontFamilies()
        {
            if (_fontFamilies.Count != 0)
                return;
            
            var assembly = Assembly.GetExecutingAssembly();
            var names = assembly.GetManifestResourceNames();
                
            if (names.Length == 0)
            {
                throw new Exception("绘制验证码字体文件加载失败");
            }

            foreach (var name in names)
            {
                _fontFamilies.Add(SKTypeface.FromStream(assembly.GetManifestResourceStream(name)));
            }
        }

        /// <summary>
        /// 获取字体
        /// </summary>
        public static SKTypeface GetFontFamily(string name)
        {
            var realName = "Epilog";
            var normalizeName = name.ToLowerInvariant();
            if (FamilyNameMapper.ContainsKey(normalizeName))
            {
                // 默认字体
                realName = FamilyNameMapper[normalizeName];
            }

            // 改用StartsWith, 某些环境下： Prefix取到的值为Prefix Endangered, Ransom取到的值为Ransom CutUpLetters
            return _fontFamilies.First(f => f.FamilyName.StartsWith(realName));
        }

        /// <summary>
        /// ACTIONJ
        /// </summary>
        public static SKTypeface Actionj => GetFontFamily("Actionj");

        /// <summary>
        /// Epilog
        /// </summary>
        public static SKTypeface Epilog => GetFontFamily("Epilog");

        /// <summary>
        /// Fresnel
        /// </summary>
        public static SKTypeface Fresnel => GetFontFamily("Fresnel");

        /// <summary>
        /// headache
        /// </summary>
        public static SKTypeface Headache => GetFontFamily("Headache");

        /// <summary>
        /// Lexo
        /// </summary>
        public static SKTypeface Lexo => GetFontFamily("Lexo");

        /// <summary>
        /// Prefix
        /// </summary>
        public static SKTypeface Prefix => GetFontFamily("Prefix");

        /// <summary>
        /// Progbot
        /// </summary>
        public static SKTypeface Progbot => GetFontFamily("Progbot");

        /// <summary>
        /// Ransom
        /// </summary>
        public static SKTypeface Ransom => GetFontFamily("Ransom");

        /// <summary>
        /// Robot
        /// </summary>
        public static SKTypeface Robot => GetFontFamily("Robot");

        /// <summary>
        /// Scandal
        /// </summary>
        public static SKTypeface Scandal => GetFontFamily("Scandal");

        /// <summary>
        /// 楷体
        /// </summary>
        public static SKTypeface Kaiti => GetFontFamily("Kaiti");
    }

    [Obsolete("拼写错误。请使用 `DefaultFontFamilies` 代替。")]
    public class DefaultFontFamilys
    {
        public static readonly DefaultFontFamilies Instance = DefaultFontFamilies.Instance;
    }
}